package stack_queue_true_023;

class MyCircularQueue {
    private int[] array;
    private int size;
    private int headIndex;
    private int lastIndex;

    public MyCircularQueue(int k) {
        // k 是容量
        array = new int[k];
        size = 0;
        headIndex = 0;
        lastIndex = 0;
    }

    public boolean enQueue(int value) {
        if (isFull()) {
            return false;
        }

        array[lastIndex] = value;
        lastIndex = (lastIndex + 1) % array.length;
        size++;

        return true;
    }

    public boolean deQueue() {
        if (isEmpty()) {
            return false;
        }

        headIndex += 1;
        if (headIndex == array.length) {
            headIndex = 0;
        }
        size--;

        return true;
    }

    public int Front() {
        if (isEmpty()) {
            return -1;
        }
        return array[headIndex];
    }

    public int Rear() {
        if (isEmpty()) {
            return -1;
        }
        int index = lastIndex;
        index = (index - 1 + array.length) % array.length;
        return array[index];
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean isFull() {
        // 元素个数 == 容量
        return size == array.length;
    }

    private static void assertTrue(boolean condition) {
        if (!condition) {
            throw new RuntimeException("断言失败");
        }
    }

    public static void main(String[] args) {
        MyCircularQueue q = new MyCircularQueue(6);
        assertTrue(q.enQueue(6) == true);
        assertTrue(q.Rear() == 6);
        assertTrue(q.Rear() == 6);
        assertTrue(q.deQueue() == true);
        assertTrue(q.enQueue(5) == true);
        assertTrue(q.Rear() == 5);
        assertTrue(q.deQueue() == true);
        assertTrue(q.Front() == -1);
        assertTrue(q.deQueue() == false);
        assertTrue(q.deQueue() == false);
        assertTrue(q.deQueue() == false);

        q.enQueue(4);
        q.enQueue(3);
        q.enQueue(2);
        q.enQueue(1);
        q.enQueue(0);
        q.enQueue(-1);
    }
}
